/*
* @Name: smartForm 智能表单
* @Author: wujuntao
* @time: 2020.09.03
* */
;(function ($) {
  'use strict';
  /*
  * 智能表单对象
  * params {Object} options 智能表单配置参数
  * */
  function smartForm (options) {
    new SmartForm(this, options);
  }

  /*
  * 构造函数
  * params {String} element form表单元素
  * params {Object} options 智能表单配置参数
  * */
  function SmartForm(element, options) {
    this.$el = element;
    this.id = element.attr('id');
    this.formDomData = '';
    this.DEFAULTS_OPTIONS = {
      scrollElement: '',
      commitElement: '',
      external: [],
      do: ''
    };
    this.options = $.extend({}, this.DEFAULTS_OPTIONS, options);
    this.init();
    this.readyFill();
    this.event();
    // this.setCookie('SmartFormElement', element);
    // localStorage.setItem('SmartFormElement')
  }

  /*
  * 给元素添加唯一标识属性
  * */
  SmartForm.prototype.init = function () {
    var self = this,
        $el = this.$el,
        formDomData = localStorage.getItem('SmartFormDomData-' + this.id) || '';
    if (formDomData === '') {
      var formData = '';
      $el.find('input').each(function (i, item) {
        if (!$(item).attr('data-smartForm-id')) {
          $(item).attr('data-smartForm-id', self.randomString(8));
        }
      });
      $el.find('textarea').each(function (i, item) {
        if (!$(item).attr('data-smartForm-id')) {
          $(item).attr('data-smartForm-id', self.randomString(8));
        }
      });
      $el.find('select').each(function (i, item) {
        if (!$(item).attr('data-smartForm-id')) {
          $(item).attr('data-smartForm-id', self.randomString(8));
        }
      });
      formData = $el.html();
      this.formDomData = formData; // 暂存dom元素，以便后面恢复
      localStorage.setItem('SmartFormDomData-' + this.id, formData);
    } else {
      $el.html(formDomData);
      this.formDomData = formDomData;
    }
  };

  /*
  * 保存表单dom元素
  * */
  SmartForm.prototype.setFormData = function () {
    var detailData = [],
        external = this.options.external;
    $('[data-smartForm-id]').each(function (i, item) {
      if (($(item).is('input') && $(item).siblings('.text-label').length === 0) || $(item).is('textarea')) {
        detailData.push({
          id: $(item).attr('data-smartForm-id'),
          type: 'input-normal',
          value: $(item).val()
        })
      } else if ($(item).is('input') && $(item).siblings('.text-label').length > 0) {
        detailData.push({
          id: $(item).attr('data-smartForm-id'),
          type: 'input-chooseBox',
          value: $(item).prop('checked')
        })
      } else if ($(item).is('select')) {
        detailData.push({
          id: $(item).attr('data-smartForm-id'),
          type: 'select-select2',
          value: $(item).val()
        })
      } else {
        detailData.push({
          id: $(item).attr('data-smartForm-id'),
          type: 'inner-text',
          value: $(item).val()
        })
      }
    });
    if (external.length > 0) {
      for (var i = 0, len = external.length; i < len; i++) {
        if (external[i].type === 'cascader' && $(external[i].selector).length !== 0) {
          detailData.push({
            id: external[i].selector,
            type: 'cascader',
            value: $(external[i].selector).cascader('getChoosedData') || ['']
          });
        }
      }
    }
    localStorage.setItem('SmartFormData-' + this.id, JSON.stringify(detailData));
  };

  /*
  * 获取表单dom元素
  * */
  SmartForm.prototype.getFormData = function () {
    // return this.getCookie('SmartFormData-' + this.id);
    return localStorage.getItem('SmartFormData-' + this.id);
  };

  /*
  * 保存滚动条信息
  * */
  SmartForm.prototype.setScrollInfo = function () {
    var scrollTop,
        scrollLeft,
        scrollElement = this.options.scrollElement;
    if (scrollElement !== '' && $(scrollElement)) {
      scrollTop = $(scrollElement).scrollTop() || 0;
      scrollLeft = $(scrollElement).scrollLeft() || 0;
    } else {
      scrollTop = this.$el.scrollTop() || 0;
      scrollLeft = this.$el.scrollLeft() || 0;
    }
    /*this.setCookie('SmartFormScrollTop-' + this.id, scrollTop);
    this.setCookie('SmartFormScrollLeft-' + this.id, scrollLeft);*/
    localStorage.setItem('SmartFormScrollTop-' + this.id, scrollTop);
    localStorage.setItem('SmartFormScrollLeft-' + this.id, scrollLeft);
  };

  /*
  * 获取滚动条信息
  * */
  SmartForm.prototype.getScrollInfo = function () {
    // return [this.getCookie('SmartFormScrollTop'), this.getCookie('SmartFormScrollLeft')];
    return [localStorage.getItem('SmartFormScrollTop-' + this.id), localStorage.getItem('SmartFormScrollLeft-' + this.id)];
  };

  /*
  * 删除所有数据
  * */
  SmartForm.prototype.deleteAllData = function () {
    localStorage.removeItem('SmartFormDomData-' + this.id);
    localStorage.removeItem('SmartFormData-' + this.id);
    localStorage.removeItem('SmartFormScrollTop-' + this.id);
    localStorage.removeItem('SmartFormScrollLeft-' + this.id);
  };

  /*
  * 保存所有信息
  * */
  SmartForm.prototype.save = function () {
    this.setScrollInfo();
    this.setFormData();
    var formDomData = localStorage.getItem('SmartFormDomData-' + this.id) || '';
    if (formDomData === '') {
      localStorage.setItem('SmartFormDomData-' + this.id, this.formDomData);
    }
  };

  /*
  * 回调函数执行和信息回填
  * */
  SmartForm.prototype.readyFill = function () {
    var options = this.options;
    if (options.do !== '') {
      options.do();
      this.fill(true);
    }
    this.fill();
  };

  /*
  * 回填所有信息
  * params {Boolean} external 是否有外部插件初始化
  * */
  SmartForm.prototype.fill = function (external) {
    var options = this.options,
        formData = JSON.parse(this.getFormData()), // 获取存储的表单数据
        scrollInfo = this.getScrollInfo(), // 获取存储的滚动条数据
        scrollElement = this.options.scrollElement; // 获取滚动条元素
    if (external && options.external !== [] && formData !== null && JSON.stringify(formData) !== '{}') {
      var eleArr = options.external;
      for (var s = 0, length = eleArr.length; s < length; s++) {
        for (var j = 0, dataLen = formData.length; j < dataLen; j++) {
          // 级联选择器
          if (eleArr[s].selector === formData[j].id && eleArr[s].type === 'cascader') {
            $(eleArr[s].selector).cascader('setChecked', formData[j].value[0]);
          }
        }
      }
    }
    if (formData !== null && JSON.stringify(formData) !== '{}') {
      // 回填数据
      for (var i = 0, len = formData.length; i < len; i++) {
        if (formData[i].type === 'input-normal') {
          $('[data-smartForm-id="'+ formData[i].id +'"]').val(formData[i].value);
        } else if (formData[i].type === 'input-chooseBox') {
          $('[data-smartForm-id="'+ formData[i].id +'"]').prop('checked', formData[i].value);
        } else if (formData[i].type === 'select-select2') {
          $('[data-smartForm-id="'+ formData[i].id +'"]').val(formData[i].value);
        } else if (formData[i].type === 'inner-text') {
          $('[data-smartForm-id="'+ formData[i].id +'"]').html(formData[i].value);
        }
      }
    }

    // 跳转到滚动条位置
    if (scrollElement !== '' && $(scrollElement)) {
      if (scrollInfo[0]) {
        $(scrollElement).scrollTop(scrollInfo[0]);
      }
      if (scrollInfo[1]) {
        $(scrollElement).scrollLeft(scrollInfo[1]);
      }
    } else {
      if (scrollInfo[0]) {
        this.$el.scrollTop(scrollInfo[0]);
      }
      if (scrollInfo[1]) {
        this.$el.scrollLeft(scrollInfo[1]);
      }
    }
  };

  /*
  * 生成随机字符串
  * params {Number} n 字符串位数
  * */
  SmartForm.prototype.randomString = function(n) {
    n = n || 8;
    var chartArr = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'],
        res = '';
    for (var i = 0; i < n; i++) {
      var index = Math.ceil(Math.random() * 35);
      res += chartArr[index];
    }
    return res;
  };

  /*
  * 提示框
  * params {String} content 提示框内容
  * params {String} type 提示框类型
  * params {String} position 提示框位置
  * */
  SmartForm.prototype._dialog = function(content, type, position) {
    type = type || 'success';
    position = position || 'top';
    content = content || '操作成功！';
    var style = '<style class="smartForm-dialog-style">' +
        '.smartForm-dialog {\n' +
        '    position: fixed;\n' +
        '    top: 24px;\n' +
        '    left: 50%;\n' +
        '    min-height: 40px;\n' +
        '    min-width: 300px;\n' +
        '    line-height: 40px;\n' +
        '    padding: 0 32px 0 16px;\n' +
        '    background: #E5F7ED;\n' +
        '    color: #00A040;\n' +
        '    transform: translateX(-50%)\n' +
        '}\n' +
        '.smartForm-dialog.danger {\n' +
        '    background: #FEEEEE;\n' +
        '    color: #F53B3B;\n' +
        '}\n' +
        '.smartForm-dialog.warning {\n' +
        '    background: #FDF5E6;\n' +
        '    color: #E78B04;\n' +
        '}\n' +
        '.smartForm-dialog.bottom {\n' +
        '    top: auto;\n' +
        '    left: auto;\n' +
        '    bottom: 24px;\n' +
        '    right: 24px;\n' +
        '    transform: none;\n' +
        '}\n' +
        '.smartForm-dialog .aidicon-close {\n' +
        '    position: absolute;\n' +
        '    top: 13px;\n' +
        '    right: 16px;\n' +
        '    cursor: pointer;\n' +
        '}\n' +
        '.smartForm-dialog .aidicon:not(.aidicon-close) {\n' +
        '    transform: translateY(1px);\n' +
        '}' +
        '</style>';
    var dom = '<div class="smartForm-dialog">\n' +
        '    <i class="aidicon aidicon-check-circle"></i>\n' +
        '    <strong>'+ content +'</strong>' +
        '    <i class="aidicon aidicon-close"></i>' +
        '</div>';


    switch (type) {
      case 'danger' : dom = '<div class="smartForm-dialog danger">\n' +
          '    <i class="aidicon aidicon-close-circle"></i>\n' +
          '    <strong>'+ content +'</strong>' +
          '    <i class="aidicon aidicon-close"></i>' +
          '</div>';
        break;
      case 'warning' : dom = '<div class="smartForm-dialog warning">\n' +
          '    <i class="aidicon aidicon-information"></i>\n' +
          '    <strong>'+ content +'</strong>' +
          '    <i class="aidicon aidicon-close"></i>' +
          '</div>';
        break;
      default: break;
    }

    $('head').remove('.smartForm-dialog-style').append(style);
    $('body').remove('.smartForm-dialog').append(dom);
    var $dialog = $('.smartForm-dialog');

    if (position === 'bottom') {
      $dialog.addClass('bottom');
    } else {
      $dialog.removeClass('bottom')
    }

    $dialog.fadeIn(300);
    setTimeout(function () {
      $dialog.fadeOut(300, function () {
        $('body').remove('.smartForm-dialog');
      });
    }, 3000);
  };

  /*
  * 事件
  * */
  SmartForm.prototype.event = function() {
    var self = this,
        $body = $('body'),
        mainId = this.id, // form表单唯一id标识
        options = self.options, // 配置参数
        scrollElement = options.scrollElement === '' ?  self.$el : $(options.scrollElement),
        inputFillData = '#' + mainId + ' input', // 输入框元素
        selectFillData = '#' + mainId + ' select', // 普通下拉框元素
        textFillData = '#' + mainId + ' textarea', // 多行输入框元素
        dialogClose = '.smartForm-dialog .aidicon-close';  // 弹框提示关闭按钮
    // 监听文本框change事件存储表单数据
    $body.off('change.inputFillData').on('change.inputFillData', inputFillData, function () {
      self.save();
    });
    // 监听文本框input事件存储表单数据
    $body.off('inputFillData').on('input propertychange.inputFillData', inputFillData, function () {
      self.save();
    });
    // 监听多行文本框change事件存储表单数据
    $body.off('change.textFillData').on('change.textFillData', textFillData, function () {
      self.save();
    });
    // 监听多行文本框input事件存储表单数据
    $body.off('textFillData').on('input propertychange.textFillData', textFillData, function () {
      self.save();
    });
    // 监听下拉框change事件存储表单数据
    $body.off('change.selectFillData').on('change.selectFillData', selectFillData, function () {
      self.save();
    });
    // 提示框的关闭图标点击事件
    $body.off('click.dialogClose').on('click.dialogClose', dialogClose, function () {
      $('.smartForm-dialog').fadeOut(300, function () {
        $('body').remove('.smartForm-dialog');
      });
    });

    // 快捷键设置
    $(window).off('keydown').on('keydown',function (e) {
      // 删除表单数据 ctrl + delete
      if (e && e.ctrlKey && (!e.shiftKey) && (!e.altKey) && e.keyCode === 46) {
        self.deleteAllData();
        self._dialog('表单缓存数据已删除，请谨慎操作。','warning');
      }
      // 存储表单数据 ctrl + shift + s
      if (e && e.ctrlKey && e.shiftKey && (!e.altKey) && e.keyCode === 83) {
        self.save();
        self._dialog('表单数据保存成功！');
      }
    });

    // 如果设置了提交按钮，则在提交之后清空所有数据
    if (options.commitElement !== '') {
      $body.off('click.commitElement').on('click.commitElement', options.commitElement, function () {
        self.deleteAllData();
      });
    } else {
      setTimeout(function () {
        self.deleteAllData();
      },3600000)
    }

    // 添加滚动条滚动监听并存储数据

    scrollElement.scroll(function () {
      var formData = localStorage.getItem('SmartFormData-' + self.id);
      if (formData && JSON.stringify(formData) !== '{}') {
        self.save();
      }
    })
  };

  $.fn.SmartForm = smartForm;
  $.fn.SmartForm.constructor = SmartForm;
})(jQuery);
